package cn.dong.edu.service.impl;

import cn.dong.base.dto.CourseDto;
import cn.dong.base.handler.CustomException;
import cn.dong.edu.domain.Chapter;
import cn.dong.edu.domain.Course;
import cn.dong.edu.domain.CourseDescription;
import cn.dong.edu.domain.Video;
import cn.dong.edu.domain.dto.*;
import cn.dong.edu.domain.query.QueryCourse;
import cn.dong.edu.feign.fillback.OssServiceImpl;
import cn.dong.edu.feign.fillback.VodServiceImpl;
import cn.dong.edu.mapper.CourseMapper;
import cn.dong.edu.service.CourseService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author You-Dong
 * @since 2021-02-06
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {


    public static final String SAVE_ERROR = "课程保存失败！";
    @Autowired
    private CourseDescriptionServiceImpl courseDesc;
    @Autowired
    private ChapterServiceImpl chapterService;
    @Autowired
    private VideoServiceImpl videoService;
    @Autowired
    private OssServiceImpl ossService;
    @Autowired
    private VodServiceImpl vodService;
    @Autowired
    private CourseMapper courseMapper;
    /**
     * 发布课程
     *
     * @param info
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String createCourse(CourseInfo info) {
        // 封装课程，复制Bean
        Course course = new Course();
        BeanUtils.copyProperties(info, course);
        // 判断保存到数据库
        if (super.baseMapper.insert(course) == 0) {
            // 保存失败！
            throw new CustomException(40000, SAVE_ERROR);
        }
        // 课程简介
        CourseDescription desc = new CourseDescription();
        desc.setDescription(info.getDescription());
        desc.setId(course.getId());
        // 保存简介描述
        if (!courseDesc.save(desc)) {
            throw new CustomException(40000, SAVE_ERROR);
        }
        // 返回课程id
        return course.getId();
    }

    /**
     * 修改课程
     *
     * @param info
     * @return
     */
    @Override
    public String updateCourse(CourseInfo info) {
        // 封装课程，复制Bean
        Course course = new Course();
        BeanUtils.copyProperties(info, course);
        // 判断保存到数据库
        if (super.baseMapper.updateById(course) == 0) {
            // 保存失败！
            throw new CustomException(40000,SAVE_ERROR);
        }
        // 修改课程封面 TODO



        // 课程简介
        CourseDescription desc = new CourseDescription();
        desc.setDescription(info.getDescription());
        desc.setId(course.getId());
        // 保存简介描述
        if (!courseDesc.updateById(desc)) {
            // 描述不存在，添加一个描述
            if (!courseDesc.save(desc)) {
                // 插入如果失败了，不允许用户操作
                throw new CustomException(40000,"描述不存在，描述添加错误！");
            }
        }
        // 返回课程id
        return course.getId();
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @Override
    public CourseInfo findById(String id) {
        // 查询课程描述和课程
        Course course = super.baseMapper.selectById(id);
        CourseDescription desc = courseDesc.getById(id);
        // 封装dto
        CourseInfo info = new CourseInfo();
        BeanUtils.copyProperties(course, info);
        if (desc != null) {
            info.setDescription(desc.getDescription());
        }
        return info;
    }

    /**
     * 提交审显示的确认信息，详细信息
     *
     * @param courseId
     * @return
     */
    @Override
    public CourseVo findDetailedInfoById(String courseId) {
        return super.baseMapper.findDetailedInfoById(courseId);
    }

    /**
     * 分页条件查询
     *
     * @param current
     * @param size
     * @param queryCourse
     * @return
     */
    @Override
    public IPage<Course> findByCondition(Integer current, Integer size, QueryCourse queryCourse) {
        if(current <= 0 || size <= 0){
            throw new CustomException(400, "错误，分页参数列表不正确");
        }
        // 开启分页
        Page<Course> page = new Page<Course>(current, size);
        // 创建条件
        QueryWrapper<Course> wrapper = new QueryWrapper<Course>();
        // 判断
        if (queryCourse == null) {
            IPage<Course> iPage = baseMapper.selectPage(page, null);
            return iPage;
        }
        if (!StringUtils.isEmpty(queryCourse.getName())) {
            wrapper.like("title", queryCourse.getName());
        }
        if (!StringUtils.isEmpty(queryCourse.getStatus())) {
            wrapper.eq("status", queryCourse.getStatus());
        }
        // 根据分查询
        return super.baseMapper.selectPage(page, wrapper);
    }

    /**
     * 删除课程
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCourse(String id) {
        QueryWrapper<Video> videoWra = new QueryWrapper<Video>();
        videoWra.eq("course_id", id);
        QueryWrapper<Chapter> characterWra = new QueryWrapper<Chapter>();
        characterWra.eq("course_id", id);
        // 删除课程封面
        QueryWrapper<Course> courseWra = new QueryWrapper<Course>();
        courseWra.eq("id", id);
        // 获取课程对象
        Course course = super.baseMapper.selectOne(courseWra);
        ossService.delFile(course.getCover());

        // 删除课程视频
        List<Video> list = videoService.list(videoWra);
        List<String> ids = new ArrayList<String>(20);
        for (Video video : list) {
            ids.add(video.getVideoSourceId());
        }
        vodService.deleteByIds(ids);


        // 删除课时
        chapterService.remove(characterWra);
        // 删除章节
        videoService.remove(videoWra);
        // 删除课程
        if (super.baseMapper.deleteById(id) ==  0) {
            throw new CustomException(40000, "删除课程失败，该视频不存在");
        }
        return true;
    }

    /**
     * 根据条件查询课程
     *
     * @param webCourseVo
     * @return
     */
    @Override
    public IPage<Course> findByCondition(Integer current, Integer size, WebCourseVo webCourseVo) {
        // 判断条件
        QueryWrapper<Course> queryWrapper = new QueryWrapper<Course>();
        // 必须是已发布
        queryWrapper.eq("status",Course.VIDEO_STATUS_NORMAL);
        // 根据一级分类
        if(!StringUtils.isEmpty(webCourseVo.getSubjectParentId())) {
            queryWrapper.eq("subject_parent_id", webCourseVo.getSubjectParentId());
        }
        // 根据二级分类查询
        if (!StringUtils.isEmpty(webCourseVo.getSubjectId())) {
            queryWrapper.eq("subject_id",webCourseVo.getSubjectId());
        }
        // 根据销量排序
        if (!StringUtils.isEmpty(webCourseVo.getSalesCountOrder())) {
            if (webCourseVo.getSalesCountOrder() == 1) {
                // 倒序
                queryWrapper.orderByDesc("buy_count");
            } else {
                // 正序
                queryWrapper.orderByAsc("buy_count");
            }
        }
        // 根据最新排序
        if (!StringUtils.isEmpty(webCourseVo.getDateOrder())) {
            if (webCourseVo.getDateOrder() == 1) {
                // 倒序
                queryWrapper.orderByDesc("gmt_create");
            } else {
                // 正序
                queryWrapper.orderByAsc("gmt_create");
            }
        }
        // 根据价格排序
        if (!StringUtils.isEmpty(webCourseVo.getPriceCountOrder())) {
            if (webCourseVo.getPriceCountOrder() == 1) {
                // 倒序
                queryWrapper.orderByDesc("price");
            } else {
                // 正序
                queryWrapper.orderByAsc("price");
            }
        }
        // 保存到分页中
        IPage<Course> page = new Page<>(current, size);

        return super.baseMapper.selectPage(page, queryWrapper);
    }

    /**
     * 根据id，查询详细信息，并且浏览数加一
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> findDetailedInfo(String id) {
        // 浏览量加一
        Course course = super.baseMapper.selectById(id);
        course.setViewCount(course.getViewCount() + 1 );
        super.baseMapper.updateById(course);
        // 全部章节
        List<ChapterVo> list = chapterService.findTotalById(id);
        // 详细信息
        WebCourseInfoVo info = super.baseMapper.findFullDetailedInfoById(id);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("totalChapter", list);
        map.put("courseInfo", info);
        return map;
    }

    /**
     * 查询前八热门课程
     * @return
     */
    @Override
    @Cacheable(value = "course", key = "'getHotCourse'")
    public List<Course> getHotCourse() {
        QueryWrapper<Course> wrapper = new QueryWrapper<Course>();
        wrapper.orderByDesc("view_count");
        wrapper.last("limit 8");
        return baseMapper.selectList(wrapper);
    }

    /**
     * 获取dto对象，用于订单服务调用
     *
     * @param id
     * @return
     */
    @Override
    public CourseDto getCourseDto(String id) {
        return super.baseMapper.getCourseDto(id);
    }

    /**
     * 增加销售数量
     *
     * @param id
     */
    @Override
    public void updateBuyCount(String id) {
        Course course = baseMapper.selectById(id);
        course.setBuyCount(course.getBuyCount() + 1);
        baseMapper.updateById(course);
    }

    /**
     * 获取今天的课程上线数量
     *
     * @param day
     * @return
     */
    @Override
    public Integer getCourseOnlineByDay(String day) {
        Integer count = courseMapper.getCourseOnlineByDay(day);
        return count;
    }


}
